
#include "dino_draw.h"
#include "dino_bmp.h"
/**
 * @brief 计算字节索引
 *
 * 根据给定的位数，计算对应的字节索引。
 *
 * @param nbit 给定的位数
 *
 * @return 对应的字节索引
 */
static uint16_t byteIndex(uint16_t nbit)
{
    return nbit / 8;
}
/**
 * @brief 计算字节数
 *
 * 根据给定的比特数，计算所需的字节数。
 *
 * @param nbit 比特数
 *
 * @return 所需的字节数
 */
static uint16_t byteCount(uint16_t nbit)
{
    return (nbit + 7) / 8;
}
/**
 * @brief 获取位索引
 *
 * 根据给定的位数值，计算其在字节中的索引位置。
 *
 * @param nbit 位数值
 *
 * @return 位索引值（0-7）
 */
static uint16_t bitIndex(uint16_t nbit)
{
    return nbit % 8;
}

void drawBmpCover(int16_t x, int16_t y, const unsigned char *bmp, uint8_t iscover)
{
    if (x >= DISPLAY_WIDTH || y >= DISPLAY_HEIGHT || bmp == (uint8_t *)0)
        return;

    uint8_t c = bmp[0];
    uint16_t w = bmp[2] | (bmp[3] << 8);
    uint16_t h = bmp[4] | (bmp[5] << 8);
    const uint8_t *data = &bmp[6];

    uint16_t byte_count = byteCount(w);
    uint16_t offset_x = 0;
    uint16_t offset_y = 0;

    if (x < 0)
    {
        w = x + w > DISPLAY_WIDTH ? DISPLAY_WIDTH - x : w;
        offset_x = 0 - x;
        x = 0;
    }

    if (y < 0)
    {
        h = y + h > DISPLAY_HEIGHT ? DISPLAY_HEIGHT - y : h;
        offset_y = 0 - y;
        y = 0;
    }
    for (uint16_t y1 = offset_y; y1 < h; y1++)
    {
        for (uint16_t x1 = offset_x; x1 < w; x1++)
        {
            uint8_t byte_index = byteIndex(x1);
            uint8_t bit_index = bitIndex(x1);
            if ((data[byte_index + y1 * byte_count] << bit_index) & 0x80)
            {
                drawPoint(x + x1 - offset_x, y + y1 - offset_y, c);
            }
            else if (iscover)
            {
                drawPoint(x + x1 - offset_x, y + y1 - offset_y, COLOR_BLACK);
            }
        }
    }
}
void drawBmp(int16_t x, int16_t y, const unsigned char *bmp)
{
    drawBmpCover(x, y, bmp, 0);
}
void drawChromeDinoRun(uint8_t index, int16_t x, int16_t y)
{
    if (index == 0)
        drawBmp(x, y, gImage_chromeDinoRun1);
    else if (index == 1)
        drawBmp(x, y, gImage_chromeDinoRun2);
}

void drawCloud(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_cloud);
}

void drawGround(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_ground);
}

void drawGameOver(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_gameover);
}

void drawLowBattery(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_lowbattery);
}

void drawLowBattery_1(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_lowbattery_1);
}

void drawRestartLogo(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_restart);
}

uint8_t getCactusCounts(void)
{
    return 5;
}

uint8_t *getCactusData(uint8_t index)
{
    uint8_t *bmp = (uint8_t *)0;
    if (index == 0)
        bmp = (uint8_t *)gImage_plant1;
    else if (index == 1)
        bmp = (uint8_t *)gImage_plant2;
    else if (index == 2)
        bmp = (uint8_t *)gImage_plant3;
    else if (index == 3)
        bmp = (uint8_t *)gImage_plant4;
    else if (index == 4)
        bmp = (uint8_t *)gImage_plant5;
    return bmp;
}

uint16_t getCactusWidth(uint8_t index)
{
    uint8_t *bmp = getCactusData(index);
    return bmp != (uint8_t *)0 ? (bmp[2] | (bmp[3] << 8)) : 0;
}

uint16_t getCactusHeight(uint8_t index)
{
    uint8_t *bmp = getCactusData(index);
    return bmp != (uint8_t *)0 ? (bmp[4] | (bmp[5] << 8)) : 0;
}

void drawCactus(int16_t x, int16_t y, uint8_t index)
{
    drawBmp(x, y, getCactusData(index));
}

uint8_t *getDinoData(uint8_t index)
{
    uint8_t *bmp = (uint8_t *)0;
    if (index == 0)
        bmp = (uint8_t *)gImage_running1;
    else if (index == 1)
        bmp = (uint8_t *)gImage_running2;
    else if (index == 2)
        bmp = (uint8_t *)gImage_flying;
    else if (index == 3)
        bmp = (uint8_t *)gImage_afraid;
    return bmp;
}

uint8_t getDinoWidth(uint8_t index)
{
    uint8_t *bmp = getDinoData(index);
    return bmp != (uint8_t *)0 ? (bmp[2] | (bmp[3] << 8)) : 0;
}

uint8_t getDinoHeight(uint8_t index)
{
    uint8_t *bmp = getDinoData(index);
    return bmp != (uint8_t *)0 ? (bmp[4] | (bmp[5] << 8)) : 0;
}

void drawDino(int16_t x, int16_t y, uint8_t index)
{
    drawBmp(x, y, getDinoData(index));
}

void drawHI(int16_t x, int16_t y)
{
    /* HI 宽17bit 高11bit 保存使用24 x 11 的字符串来实现 */
    drawBmp(x, y, gImage_HI);
}
void drawNum(int16_t x, int16_t y, uint32_t num, uint8_t color)
{
    for (uint8_t i = 5; i > 0; i--)
    {
        uint8_t num_index = (num % 10);
        /* number 字符的宽度10x11 保存使用16 x 11 的字符串来实现 */
        const uint8_t *data = &gImage_number[num_index][0];
        for (uint8_t y1 = 0; y1 < 11; y1++)
        {
            for (uint8_t x1 = 0; x1 < 16; x1++)
            {
                uint8_t byte_index = byteIndex(x1);
                uint8_t bit_index = bitIndex(x1);
                if (data[byte_index + y1 * 2] & (0x80 >> bit_index))
                    drawPoint(x + x1 + (i - 1) * 10, y + y1, color);
            }
        }
        num /= 10;
    }
}

void drawDinoGirl(int16_t x, int16_t y, uint8_t index)
{
    switch (index)
    {
    case 0:
        drawBmp(x, y, gImage_dino_girl_running1);
        break;
    case 1:
        drawBmp(x, y, gImage_dino_girl_running2);
        break;
    case 2:
        drawBmp(x, y, gImage_dino_girl_normal);
        break;
    default:
        break;
    }
}

void drawDinoSmail(int16_t x, int16_t y)
{
    drawBmpCover(x + 13, y + 1, gImage_dino_smile, 1);
}

void drawDinoGirlSmail(int16_t x, int16_t y)
{
    drawBmpCover(x + 6, y + 3, gImage_dino_smile, 1);
}

void drawCongratulations(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_congratulations);
}

void drawYOUWIN(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_youwin);
}

void drawIFoundU(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_ifoundu);
}

void drawMyLove(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_mylove);
}

void drawHeart(int8_t index, int16_t x, int16_t y)
{
    switch (index)
    {
    case 0:
        drawBmp(x, y, gImage_heart1);
        break;
    case 1:
        drawBmp(x, y, gImage_heart2);
        break;
    default:
        break;
    }
}

void drawqrCode(int16_t x, int16_t y)
{
    drawBmp(x, y, gImage_qrcode);
}